﻿// ================================================================================
// The contents of this file are subject to the Mozilla Public License
// Version 2.0 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/2.0/
//
// Software distributed under the License is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
// License for the specific language governing rights and limitations
// under the License.
// ================================================================================
using System.Drawing;
using System.Linq;
using Reflex.Framework.Communication;
using Reflex.Interface.Aion;

namespace Reflex.Os.Aion.Service
{
	/// <summary>
	/// Represents the IntelRadarService
	/// </summary>
	public class RadarRenderService : ViewModelCommunication
	{
		/// <summary>
		/// Contains the application instance.
		/// </summary>
		private IAionInstance _hAionInstance;

		/// <summary>
		/// Contains the radar service.
		/// </summary>
		private RadarService _hRadarService;

		/// <summary>
		/// Contains the position on the X-axis.
		/// </summary>
		private float _X;

		/// <summary>
		/// Contains the position on the X-axis.
		/// </summary>
		private float _Y;

		/// <summary>
		/// Initialize a new instance of the IntelRadarService class.
		/// </summary>
		/// <param name="hAionInstance">Contains the application instance.</param>
		/// <param name="hActor">Contains the actor.</param>
		/// <param name="hRadarService">Contains the radar service.</param>
		public RadarRenderService( IAionInstance hAionInstance, IActor hActor, RadarService hRadarService )
		{
			// Set the application instance.
			_hAionInstance = hAionInstance;

			// Set the radar service.
			_hRadarService = hRadarService;

			// Set the actor.
			Actor = hActor;

			// Set the status indicating whether this is a player;
			Player = hActor is IActorPlayer;

			// Update the bitmap.
			Update();
		}

		/// <summary>
		/// Contains the actor.
		/// </summary>
		public IActor Actor { get; set; }

		/// <summary>
		/// Contains the bitmap.
		/// </summary>
		public Bitmap Bitmap { get; set; }

		/// <summary>
		/// Indicates whether this is a player.
		/// </summary>
		public bool Player { get; set; }

		/// <summary>
		/// Update the bitmap.
		/// </summary>
		public void Update()
		{
			// Check if this is a player.
			if ( Player )
			{
				// Retrieve the actor as a player actor.
				IActorPlayer hActorPlayer = Actor as IActorPlayer;

				// Check if this is an agressive player.
				if ( hActorPlayer.Attitude == ActorCreatureAttitude.Aggressive )
				{
					// Check if the player is dead.
					if ( hActorPlayer.Stance == ActorCreatureStance.Dead )
					{
						// Prepare the graphics for this actor.
						Bitmap = _hRadarService.Enemy ? global::Reflex.Os.Aion.Properties.Resource.RadarPlayerAggressiveDead : null;
					}
					// Otherwise the player is alive.
					else 
					{
						// Prepare the graphics for this actor.
						Bitmap = _hRadarService.Enemy ? global::Reflex.Os.Aion.Properties.Resource.RadarPlayerAggressive : null;
					}
				}
				// Otherwise check if this player is in my group.
				else if ( _hAionInstance.Group.SingleOrDefault( x => x.Id == Actor.Id ) != null )
				{
					// Check if the player is dead.
					if ( hActorPlayer.Stance == ActorCreatureStance.Dead )
					{
						// Prepare the graphics for this actor.
						Bitmap = _hRadarService.Group ? global::Reflex.Os.Aion.Properties.Resource.RadarPlayerGroupDead : null;
					}
					// Otherwise the player is alive.
					else 
					{
						// Prepare the graphics for this actor.
						Bitmap = _hRadarService.Enemy ? global::Reflex.Os.Aion.Properties.Resource.RadarPlayerGroup : null;
					}
				}
				// Otherwise this is a friendly player.
				else
				{
					// Check if the player is dead.
					if ( hActorPlayer.Stance == ActorCreatureStance.Dead )
					{
						// Prepare the graphics for this actor.
						Bitmap =_hRadarService.Friendly ?  global::Reflex.Os.Aion.Properties.Resource.RadarPlayerFriendlyDead : null;
					}
					// Otherwise the player is alive.
					else 
					{
						// Prepare the graphics for this actor.
						Bitmap = _hRadarService.Friendly ? global::Reflex.Os.Aion.Properties.Resource.RadarPlayerFriendly : null;
					}
				}
			}
			// Otherwise check if the actor is a npc.
			else if ( Actor is IActorNpc )
			{
				// Retrieve the actor as a npc.
				IActorNpc hActorNpc = Actor as IActorNpc;

				// Check if this is an actor we searched for.
				if ( !string.IsNullOrEmpty( _hAionInstance.Controller.Search ) && hActorNpc.Name != null && hActorNpc.Name.Equals( _hAionInstance.Controller.Search ))
				{
					// Prepare the graphics for this actor.
					Bitmap = global::Reflex.Os.Aion.Properties.Resource.RadarWhere;
				}
				// Check if this npc is a kisk.
				else if ( hActorNpc.Name != null && hActorNpc.Name.English.Contains( "Kisk" ))
				{
					// Check if this is an enemy kisk.
					if ( hActorNpc.Attitude == ActorCreatureAttitude.Aggressive )
					{
						// Prepare the graphics for this actor.
						Bitmap = _hRadarService.Kisk ? global::Reflex.Os.Aion.Properties.Resource.RadarKiskEnemy : null;
					}
					// Otherwise it is a friendly kisk.
					else
					{
						// Prepare the graphics for this actor.
						Bitmap = _hRadarService.Kisk ? global::Reflex.Os.Aion.Properties.Resource.RadarKiskFriendly : null;
					}
				}
				// Otherwise this is a regular npc.
				else
				{
					// Check if this is an agressive npc.
					if ( hActorNpc.Attitude == ActorCreatureAttitude.Aggressive )
					{
						// Prepare the graphics for this actor.
						Bitmap = _hRadarService.Creature ? global::Reflex.Os.Aion.Properties.Resource.RadarNpcAggressive : null;
					}
					// Otherwise check if this a friendly npc.
					else if ( hActorNpc.Attitude == ActorCreatureAttitude.Friendly )
					{
						// Prepare the graphics for this actor.
						Bitmap = _hRadarService.Creature ? global::Reflex.Os.Aion.Properties.Resource.RadarNpcFriendly : null;
					}
					// Otherwise this is a passive npc.
					else
					{
						// Prepare the graphics for this actor.
						Bitmap = _hRadarService.Creature ? global::Reflex.Os.Aion.Properties.Resource.RadarNpcPassive : null;
					}
				}
			}
			// Otherwise check if this actor is a gatherable actor.
			else if ( Actor is IActorGatherable )
			{
				// Retrieve the actor as a gatherable.
				IActorGatherable hActorGatherable = Actor as IActorGatherable;
				
				// Check if this is an actor we searched for.
				if ( !string.IsNullOrEmpty( _hAionInstance.Controller.Search ) && hActorGatherable.Name != null && hActorGatherable.Name.Equals( _hAionInstance.Controller.Search ))
				{
					// Prepare the graphics for this actor.
					Bitmap = global::Reflex.Os.Aion.Properties.Resource.RadarWhere;
				}
				// Otherwise this is a different gatherable.
				else
				{
					// Prepare the graphics for this actor.
					Bitmap = _hRadarService.Gatherable ? global::Reflex.Os.Aion.Properties.Resource.RadarGatherable : null;
				}
			}
			// Otherwise this actor is an object.
			else
			{
				// Retrieve the actor as an object.
				IActorObject hActorObject = Actor as IActorObject;
				
				// Check if this is an actor we searched for.
				if ( !string.IsNullOrEmpty( _hAionInstance.Controller.Search ) && hActorObject.Name != null && hActorObject.Name.Equals( _hAionInstance.Controller.Search ))
				{
					// Prepare the graphics for this actor.
					Bitmap = global::Reflex.Os.Aion.Properties.Resource.RadarWhere;
				}
				// Otherwise this is a different object.
				else
				{
					// Prepare the graphics for this actor.
					Bitmap = _hRadarService.Object ? global::Reflex.Os.Aion.Properties.Resource.RadarGatherable : null;
				}
			}
		}

		/// <summary>
		/// Contains the position on the X-axis.
		/// </summary>
		public float X
		{
			get
			{
				// Retrieve the property.
				return _X;
			}
			set
			{
				// Set the property.
				_X = value - ( Bitmap.Width / 2 );
			}
		}

		/// <summary>
		/// Contains the position on the Y-axis.
		/// </summary>
		public float Y
		{
			get
			{
				// Retrieve the property.
				return _Y;
			}
			set
			{
				// Set the property.
				_Y = value - ( Bitmap.Height / 2 );
			}
		}
	}
}